package logger

import (
	"fmt"
	"log"
	"os"
	"sync"
)

const (
	LEmerg int = iota
	LAlert
	LCrit
	LError
	LWarn
	LNotice
	LInfo
	LDebug
)

var levelName []string = []string{
	"Emerg",
	"Alert",
	"Crit",
	"Error",
	"Warn",
	"Notice",
	"Info",
	"Debug",
}

type Logger struct {
	Level   int // 日志级别
	LogFile string
	file    *os.File
	out     *log.Logger
	mu      sync.Mutex
}

// New creates a new Logger.
// The level variable sets the level of log
// The file variable sets destination to which log data will be written.
func New(level int, file string) (*Logger, error) {
	f, err := os.OpenFile(file, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
	if err != nil {
		return nil, err
	}
	// defer f.Close()

	logger := log.New(f, "", log.Llongfile|log.LUTC|log.LstdFlags)
	l := &Logger{}
	l.Level = level + 1
	l.LogFile = file
	l.out = logger

	return l, nil
}

//
func (l *Logger) Close() {
	l.file.Close()
}

func (l *Logger) Debug(format string, a ...interface{}) error {
	if l.Level > LDebug {
		l.mu.Lock()
		defer l.mu.Unlock()

		l.out.Printf(fmt.Sprintf("[%s] ", levelName[LDebug])+format, a...)
	}
	return nil
}

func (l *Logger) Info(format string, a ...interface{}) error {
	if l.Level > LInfo {
		l.mu.Lock()
		defer l.mu.Unlock()
		l.out.Printf(fmt.Sprintf("[%s] ", levelName[LInfo])+format, a...)
	}
	return nil
}

func (l *Logger) Notice(format string, a ...interface{}) {
	if l.Level > LNotice {
		l.mu.Lock()
		defer l.mu.Unlock()
		l.out.Printf(fmt.Sprintf("[%s] ", levelName[LNotice])+format, a...)
	}
}

func (l *Logger) Warn(format string, a ...interface{}) {
	if l.Level > LWarn {
		l.mu.Lock()
		defer l.mu.Unlock()
		l.out.Printf(fmt.Sprintf("[%s] ", levelName[LWarn])+format, a...)
	}
}

func (l *Logger) Error(format string, a ...interface{}) {
	if l.Level > LError {
		l.mu.Lock()
		defer l.mu.Unlock()
		l.out.Printf(fmt.Sprintf("[%s] ", levelName[LError])+format, a...)
	}
}
